package com.smedi.ismedi.constructionproject.core.domain.service.impl;

import com.smedi.ismedi.constructionproject.core.domain.aggregatemodel.ProjectBasic;
import com.smedi.ismedi.constructionproject.core.domain.repository.ProjectBasicRepository;
import com.smedi.ismedi.constructionproject.core.domain.service.ProjectBasicDomainService;
import com.smedi.ismedi.constructionproject.core.infrastructure.constant.CustomError;
import com.smedi.ismedi.constructionproject.core.infrastructure.enumerate.EpcTypeEnum;
import com.smedi.ismedi.constructionproject.core.infrastructure.enumerate.ProjectTypeEnum;
import com.smedi.ismedi.constructionproject.core.port.adapter.service.OrganizationRemoteApiService;
import com.smedi.ismedi.web.starter.exception.LogicException;
import com.smedi.ismedi.web.starter.util.DozerUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author: xulinjun
 * @Date: 2021-6-21 10:32
 */
@Slf4j
@Service
@AllArgsConstructor
public class ProjectBasicDomainServiceImpl implements ProjectBasicDomainService {
    private final OrganizationRemoteApiService organizationRemoteApiService;
    private final ProjectBasicRepository projectBasicRepository;

    private final DozerUtil dozerUtil;

    @Override
    public ProjectBasic saveInfo(ProjectBasic data) {
        ProjectBasic basic;
        if (data.getProjectId() != null) {
            basic = projectBasicRepository.selectByProjectId(data.getProjectId());
            if (basic == null) {
                throw LogicException.raise(CustomError.PROJECT_NOT_EXIST);
            }
        } else {
            basic = new ProjectBasic();
        }

        basic.setHrOrganizationId(data.getHrOrganizationId())
                .setProjectName(data.getProjectName())
                .setProjectCode(data.getProjectCode())
                .setProjectShortName(data.getProjectShortName())
                .setProjectManager(data.getProjectManager())
                .setMobile(data.getMobile())
                .setConstructionPermit(data.getConstructionPermit())
                .setProjectCategory(data.getProjectCategory())
                .setProjectCost(data.getProjectCost())
                .setProjectStatus(data.getProjectStatus())
                .setProjectAddress(data.getProjectAddress())
                .setProjectMapLocation(data.getProjectMapLocation())
                .setContractSigningDate(data.getContractSigningDate())
                .setContractDurationBegin(data.getContractDurationBegin())
                .setContractDurationEnd(data.getContractDurationEnd())
                .setActualDurationBegin(data.getActualDurationBegin())
                .setActualDurationEnd(data.getActualDurationEnd())
                .setEpcType(data.getEpcType())
                .setEpcUnit(data.getEpcUnit())
                .setProjectMember(data.getProjectMember())
                .setGeneralContractor(data.getGeneralContractor())
                .setSupervisionUnit(data.getSupervisionUnit())
                .setProjectAddressProvince(data.getProjectAddressProvince())
                .setProjectAddressCity(data.getProjectAddressCity())
                .setProjectType(data.getProjectType())
                .setFinishDate(data.getFinishDate())
                .setContractCost(data.getContractCost());

        // 手机号格式校验
        if (!StringUtils.isEmpty(basic.getMobile())) {
            Pattern p = Pattern.compile("^[1][0-9]{10}$");
            Matcher m = p.matcher(basic.getMobile());
            if (!m.matches()) {
                throw LogicException.raise(CustomError.MOBILE_FORMAT_ERROR);
            }
        }
        // 施工许可证长度
        /*if (!StringUtils.isEmpty(basic.getConstructionPermit())) {
            if (basic.getConstructionPermit().length() != 18) {
                throw LogicException.raise(CustomError.CONSTRUCTION_PERMIT_LENGTH_ERROR);
            }
        }*/
        // 判断所选的企业组织节点是否允许创建项目
        if (basic.getHrOrganizationId() != null) {
            boolean validate = organizationRemoteApiService.checkHrOrganizationCanHasProjectAvailable(basic.getHrOrganizationId());
            if (!validate) {
                throw LogicException.raise(CustomError.HR_ORGANIZATION_CAN_NOT_HAS_PROJECT);
            }
        } else {
            throw LogicException.raise(CustomError.HR_ORGANIZATION_ID_MISS);
        }
        // 判断项目编码是否重复
        if (!StringUtils.isEmpty(basic.getProjectCode())) {
            if (duplicateProjectCode(basic.getProjectCode(), basic.getProjectId())) {
                throw LogicException.raise(CustomError.PROJECT_CODE_DUPLICATE);
            }
        }

        // 判断合同工期填写
        if (basic.getContractDurationBegin() != null && basic.getContractDurationEnd() != null) {
            if (basic.getContractDurationBegin().isAfter(basic.getContractDurationEnd())) {
                throw LogicException.raise(CustomError.CONTRACT_DURATION_RANGE_ERROR);  // 合同工期大小校验
            }
        }

        // 判断实际工期填写
        if (basic.getActualDurationBegin() != null && basic.getActualDurationEnd() != null) {
            if (basic.getActualDurationBegin().isAfter(basic.getActualDurationEnd())) {
                throw LogicException.raise(CustomError.ACTUAL_DURATION_RANGE_ERROR);
            }
        }

        // TODO 待前端修改后取消注释
        // 判断总承包模式与项目成员方的关系
        /*if (EpcTypeEnum.SELF_SUPPORT.getValue().equals(basic.getEpcType())) {
            if (!StringUtils.isEmpty(basic.getProjectMember())) {
                throw LogicException.raise(CustomError.PROJECT_MEMBER_IS_NOT_EMPTY);
            }
        } else if (EpcTypeEnum.CONSORTIUM.getValue().equals(basic.getEpcType()) || EpcTypeEnum.SELF_SUPPORT_CONSORTIUM.getValue().equals(basic.getEpcType())) {
            if (StringUtils.isEmpty(basic.getProjectMember())) {
                throw LogicException.raise(CustomError.PROJECT_MEMBER_IS_EMPTY);
            }
        }*/

        // 保存数据
        return (data.getProjectId() == null) ? projectBasicRepository.doInsert(basic) : projectBasicRepository.doUpdate(basic);
    }

    @Override
    public Boolean updateInfo(ProjectBasic projectBasic) {
        return projectBasicRepository.updateProjectBasic(projectBasic);
    }

    @Override
    public boolean duplicateProjectCode(String projectCode, Long projectId) {
        return projectBasicRepository.selectProjectCodeCount(projectCode, projectId) > 0;
    }

    @Override
    public boolean validateMobileFormat(String mobile) {
        return Pattern.matches("^(((13[0-9])|(14[579])|(15([0-3]|[5-9]))|(16[6])|(17[0135678])|(18[0-9])|(19[89]))\\d{8})$", mobile);
    }

    @Override
    public boolean validateProject(Long projectId) {
        ProjectBasic projectBasic = projectBasicRepository.selectByProjectId(projectId);
        return projectBasic != null;
    }

    @Override
    public boolean validateHrOrgHasProject(Long hrOrganizationId) {
        return projectBasicRepository.selectProjectCountByHrOrganizationId(hrOrganizationId) > 0;
    }

    @Override
    public void deleteProjectBasic(Long projectId) {
        ProjectBasic projectBasic = projectBasicRepository.selectByProjectId(projectId);
        if (projectBasic != null) {
            projectBasicRepository.doDeleteByProjectId(projectId);
        } else {
            throw LogicException.raise(CustomError.PROJECT_NOT_EXIST);
        }
    }

    @Override
    public Long getDurationDays(LocalDate date1, LocalDate date2) {
        if (date1 != null && date2 != null) {
            if (date1.isAfter(date2)) {
                return null;
            } else {
                Long days = date2.toEpochDay() - date1.toEpochDay();
                return days;
            }
        } else {
            return null;
        }
    }

    @Override
    public long updateProjectByName(String projectName, String dingDeptKey) {
        return projectBasicRepository.updateProjectByProjectName(projectName,dingDeptKey);
    }
}
